/**
 * Responsible for maintaining the state of the game
 */

package bbchess;

import FICS.SimpleFICSInterface;
import TelnetClient.TelnetInterface;
import bbchess.dialogs.HistoryDialog;
import bbchess.dialogs.NewGamePVPInternetDialog;
import bbchess.dialogs.CapturedPiecesDialog;
import bbchess.units.ChessBoard;
import bbchess.util.SoundLoader;
import chessengine.EngineInterface;

/**
 *
 * @author Tyler Eastman
 */
public class GameManager {

    // Declare variables
    private String turn;
    private int moveNumber;
    private ChessBoard board;
    private boolean canWhiteMove;
    private boolean canBlackMove;
    private StatusPanel statusPanel;
    private CapturedPiecesDialog statusDialog;
    private HistoryDialog historyDialog;
    private String whiteName;
    private String blackName;
    private String computer;
    private int depth;
    private String playerName;
    private NewGamePVPInternetDialog pvpdialog;
    private boolean playingOnline;
    private TelnetInterface telnetInterface;
    private SimpleFICSInterface ficsInterface;

    public GameManager(ChessBoard board) {
        // Initialize variables
        whiteName = "Player 1";
        blackName = "Player 2";
        this.board = board;
        turn = "white";
        computer = null;
        moveNumber = 1;
        this.statusPanel = (StatusPanel) board.gui.statusPanel;
        this.statusDialog = (CapturedPiecesDialog) board.gui.capturedPiecesDialog;
        this.historyDialog = (HistoryDialog) board.gui.historyDialog;

        canWhiteMove = true;
        canBlackMove = true;

        playingOnline = false;

        // computer settings
        depth = 5;
    }

    public void newGamePVC(int depth) {
        resetGame();
        board.gui.engineInterface = new EngineInterface(board.gui, false);
        board.gui.enableEngineMenuItem(true);
        this.setDepth(depth);

        // set players names
        statusPanel.setWhiteName(whiteName);
        statusPanel.setBlackName(blackName);
        statusPanel.repaint();

        // set movement parameters
        if (computer.equals("white")) {
            canWhiteMove = false;
            canBlackMove = true;
            board.changeBoardOrientation();
            board.gui.engineInterface.waitForNextMove(depth);
        }
        else {
            canWhiteMove = true;
            canBlackMove = false;
        }
    }

    public void newGamePVPLocal() {
        resetGame();

        // set players names
        statusPanel.setWhiteName(whiteName);
        statusPanel.setBlackName(blackName);
        statusPanel.repaint();

        // sets the movement parameters
        canWhiteMove = true;
        canBlackMove = true;
    }

    public void newGamePVPNetwork(NewGamePVPInternetDialog pvpdialog, String user, String pass) {

        this.pvpdialog = pvpdialog;

        telnetInterface = board.gui.getTelnetInterface(user, pass);
        ficsInterface = telnetInterface.getFicsInterface();

        board.gui.setEnableNetworkViewMenuItem(true);
        board.gui.setNetworkViewMenuItemSelected(true);
    }

    public SimpleFICSInterface getFicsInterface() {
        return ficsInterface;
    }

    public void networkGameStart() {
        resetGame();
        
        playingOnline = true;
        
        statusPanel.setWhiteName(whiteName);
        statusPanel.setBlackName(blackName);

        if (playerName.equals(whiteName)) {
            canWhiteMove = true;
            canBlackMove = false;
        }
        else {
            canWhiteMove = false;
            canBlackMove = true;
            board.changeBoardOrientation();
        }

        SoundLoader.newGame();

        statusPanel.repaint();       

    }

    /*
     * Resets the game
     */
    public void resetGame() {
        // ChessBoard
        board.resetBoard();

        playingOnline = false;

        //statusPanel
        turn = "white";
        moveNumber = 1;
        statusPanel.setCheckLabelText("");

        // stop the chess engine
        try {
            board.gui.enableEngineMenuItem(false);
            board.gui.engineInterface.stopEngine();
            board.gui.engineInterface.dispose();
        } catch (Exception ex) {/*engine not running, dont worry about it*/}

        //statusDialog
        statusDialog.clearCapturedPieces();
        statusPanel.resetTimers();
        historyDialog.clearHistory();
    }

    /**
     * Pauses the game.
     */
    public void pause() {
        statusPanel.pause();
    }

    /**
     * @return the turn
     */
    public String getTurn() {
        return turn;
    }

    /**
     * @param turn the turn to set
     */
    public void setTurn(String turn) {
        this.turn = turn;
    }

    /**
     * @return the moveNumber
     */
    public int getMoveNumber() {
        return moveNumber;
    }

    /**
     * @param moveNumber the moveNumber to set
     */
    public void setMoveNumber(int moveNumber) {
        this.moveNumber = moveNumber;
    }

    public void incrementMoveNumber() {
        moveNumber += 1;
    }

    public boolean canMove() {
        if (turn.equals("black")) {
            return canBlackMove();
        }

        if (turn.equals("white")) {
            return canWhiteMove();
        }

        // else return false (if error)
        return false;
    }

    /**
     * Pauses and ends the game so that no players can move.
     */
    public void endGame() {
        pause();
        playingOnline = false;
        canWhiteMove = false;
        canBlackMove = false;
    }

    /**
     * @return the whiteName
     */
    public String getWhiteName() {
        return whiteName;
    }

    /**
     * @param whiteName the whiteName to set
     */
    public void setWhiteName(String whiteName) {
        this.whiteName = whiteName;
    }

    /**
     * @return the blackName
     */
    public String getBlackName() {
        return blackName;
    }

    /**
     * @param blackName the blackName to set
     */
    public void setBlackName(String blackName) {
        this.blackName = blackName;
    }

    /**
     * @return the computer
     */
    public String getComputer() {
        return computer;
    }

    /**
     * @param computer the computer to set
     */
    public void setComputer(String computer) {
        this.computer = computer;
    }

    /**
     * @return the depth
     */
    public int getDepth() {
        return depth;
    }

    /**
     * @param depth the depth to set
     */
    public void setDepth(int depth) {
        this.depth = depth;
    }

    /**
     * @return the canWhiteMove
     */
    public boolean canWhiteMove() {
        return canWhiteMove;
    }

    /**
     * @return the canBlackMove
     */
    public boolean canBlackMove() {
        return canBlackMove;
    }

    /**
     * @return the playingOnline
     */
    public boolean isPlayingOnline() {
        return playingOnline;
    }

    /**
     * @return the playerName
     */
    public String getPlayerName() {
        return playerName;
    }

    /**
     * @param playerName the playerName to set
     */
    public void setPlayerName(String playerName) {
        this.playerName = playerName;
    }

    /**
     * @return the pvpdialog
     */
    public NewGamePVPInternetDialog getPvpdialog() {
        return pvpdialog;
    }
}
